package com.oanda.blackberry.view;

import java.util.Enumeration;
import java.util.Hashtable;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ListField;

import com.oanda.blackberry.restapi.PositionsListResponse;
import com.oanda.blackberry.restapi.Quote;
import com.oanda.blackberry.restapi.Symbol;
import com.oanda.blackberry.restapi.TradeListResponse;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.Model;
import com.oanda.blackberry.util.StringUtils;
import com.oanda.blackberry.util.log.Logger;

public class TradesListField {
    private Object[] listData;
    private ListField listField;
    private ListCallBack listFieldCallBack = null;
    private Quote[] quotes;
    TradesView callback;

    public TradesListField(Object[] tradesList) {
        this.listFieldCallBack = new ListCallBack();

        this.listField = new ListField() {
            protected void drawFocus(Graphics graphics, boolean on) {
            }

            protected int moveFocus(int amount, int status, int time) {
                int ret = super.moveFocus(amount, status, time);
                invalidate();
                return ret;
            }

            protected void moveFocus(int x, int y, int status, int time) {
                int oldSelection = getSelectedIndex();
                super.moveFocus(x, y, status, time);
                int newSelection = getSelectedIndex();

                if (oldSelection != -1) {
                    invalidate(oldSelection);
                }

                if (newSelection != -1) {
                    invalidate(newSelection);
                } else {
                    setSelectedIndex(oldSelection);
                    invalidate(oldSelection);
                }
            }

            protected void onDisplay() {
                super.onDisplay();
            }

            protected void onUndisplay() {
                super.onUndisplay();
            }
        };
        this.listField.setEmptyString("", 6);

        if ((tradesList instanceof TradeListResponse[])) {
            TradeListResponse.sort((TradeListResponse[]) (TradeListResponse[]) tradesList);
        }

        this.listData = tradesList;
        this.listField.setRowHeight(70);

        this.listField.setCallback(this.listFieldCallBack);

        int elementLength = tradesList.length;

        for (int count = 0; count < elementLength; count++)
            this.listField.insert(count);
    }

    public void setQuotes(Quote[] quotes) {
        this.quotes = quotes;
        if (this.listField != null)
            this.listField.invalidate();
    }

    public ListField getList() {
        return this.listField;
    }

    public Object getTradeListSelected() {
        int index = this.listField.getSelectedIndex();

        if ((index > -1) && ((this.listData[index] instanceof TradeListResponse)))
            return (TradeListResponse) this.listData[index];
        if ((index > -1) && ((this.listData[index] instanceof PositionsListResponse))) {
            return (PositionsListResponse) this.listData[index];
        }

        return null;
    }

    public Object[] getTradeListResponses() {
        return this.listData;
    }

    void removeClosedPositions(String closed) {
        if (this.listData == null)
            return;
        if (this.listField == null)
            return;
        if (closed == null)
            return;

        int selected = this.listField.getSelectedIndex();

        if ((closed == null) || ((closed != null) && (closed.length() == 0)))
            return;

        Hashtable v = new Hashtable();
        Hashtable h = new Hashtable();
        for (int i = 0; i < this.listData.length; i++) {
            v.put(((PositionsListResponse) this.listData[i]).getSymbol(), this.listData[i]);
            h.put(((PositionsListResponse) this.listData[i]).getSymbol(), new Integer(i));
        }

        v.remove(closed);

        Enumeration e = v.elements();
        this.listData = new PositionsListResponse[v.size()];
        int i = 0;
        while (e.hasMoreElements()) {
            this.listData[i] = ((PositionsListResponse) e.nextElement());
            i++;
        }

        Runnable r = new Runnable() {
            private int selected;

            public void run() {
                TradesListField.this.listField.setCallback(TradesListField.this.listFieldCallBack);
                TradesListField.this.listField.setSize(TradesListField.this.listData.length);
                if (TradesListField.this.listData.length > this.selected)
                    TradesListField.this.listField.setSelectedIndex(this.selected);
                TradesListField.this.listField.invalidate();

                if ((TradesListField.this.listData == null)
                        || ((TradesListField.this.listData != null) && (TradesListField.this.listData.length == 0)))
                    StatusView2.showInfoDialog("No Open Positions.", new OKDialogListener() {
                        public void performAction(Object o) {
                            TradesListField.this.callback.popScreen();
                        }
                    }, false);
            }
        };
        UiApplication.getUiApplication().invokeLater(r);
    }

    void removeClosedTrade(String closedId) {
        if (this.listData == null)
            return;
        if (this.listField == null)
            return;

        int selected = this.listField.getSelectedIndex();

        if ((closedId == null) || ((closedId != null) && (closedId.length() == 0)))
            return;

        Logger.log("removeClosedTrade: -" + closedId + "-");

        Hashtable v = new Hashtable();

        for (int i = 0; i < this.listData.length; i++) {
            Logger.log("put: -"
                    + new Long(((TradeListResponse) this.listData[i]).getId()).toString() + "-");
            v.put(new Long(((TradeListResponse) this.listData[i]).getId()), this.listData[i]);
        }

        Logger.log("v size: " + String.valueOf(v.size()));
        try {
            long l = Long.parseLong(closedId);
            v.remove(new Long(l));
            Logger.log("v size: " + String.valueOf(v.size()));
        } catch (NumberFormatException ne) {
            return;
        }

        Enumeration e = v.elements();
        this.listData = new TradeListResponse[v.size()];
        int i = 0;
        while (e.hasMoreElements()) {
            this.listData[i] = ((TradeListResponse) e.nextElement());
            i++;
        }

        Runnable r = new Runnable() {
            private int selected;

            public void run() {
                TradesListField.this.listField.setCallback(TradesListField.this.listFieldCallBack);
                TradesListField.this.listField.setSize(TradesListField.this.listData.length);
                if (TradesListField.this.listData.length > this.selected) {
                    TradesListField.this.listField.setSelectedIndex(this.selected);
                }
                TradesListField.this.listField.invalidate();

                if ((TradesListField.this.listData == null)
                        || ((TradesListField.this.listData != null) && (TradesListField.this.listData.length == 0)))
                    StatusView2.showInfoDialog("No Open Trades.", new OKDialogListener() {
                        public void performAction(Object o) {
                            TradesListField.this.callback.popScreen();
                        }
                    }, false);
            }
        };
        UiApplication.getUiApplication().invokeLater(r);
    }

    void remove(long[] closed) {
        if (this.listData == null)
            return;
        if (this.listField == null)
            return;
        if (closed == null)
            return;

        int selected = this.listField.getSelectedIndex();

        if (!(this.listData instanceof TradeListResponse[])) {
            Logger.log("listData not instanceof TradeListResponse[]");
            return;
        }

        Hashtable v = new Hashtable();
        Hashtable h = new Hashtable();
        for (int i = 0; i < this.listData.length; i++) {
            v.put(new Long(((TradeListResponse) this.listData[i]).getId()), this.listData[i]);
            h.put(new Long(((TradeListResponse) this.listData[i]).getId()), new Integer(i));
        }

        for (int i = 0; i < closed.length; i++) {
            long l = closed[i];
            if (v.get(new Long(l)) != null) {
                v.remove(new Long(l));
            }

        }

        Enumeration e = v.elements();
        this.listData = new TradeListResponse[v.size()];
        int i = 0;
        while (e.hasMoreElements()) {
            this.listData[i] = ((TradeListResponse) e.nextElement());
            i++;
        }

        TradeListResponse.sort((TradeListResponse[]) (TradeListResponse[]) this.listData);

        Runnable r = new Runnable() {
            private int selected;

            public void run() {
                try {
                    TradesListField.this.listField
                            .setCallback(TradesListField.this.listFieldCallBack);
                    TradesListField.this.listField.setSize(TradesListField.this.listData.length);
                    if (TradesListField.this.listData.length > this.selected)
                        TradesListField.this.listField.setSelectedIndex(this.selected);
                    TradesListField.this.listField.invalidate();

                    if ((TradesListField.this.listData == null)
                            || ((TradesListField.this.listData != null) && (TradesListField.this.listData.length == 0)))
                        StatusView2.showInfoDialog("No Open Trades.", new OKDialogListener() {
                            public void performAction(Object o) {
                                TradesListField.this.callback.popScreen();
                            }
                        }, false);
                } catch (ArrayIndexOutOfBoundsException a) {
                }
            }
        };
        UiApplication.getUiApplication().invokeLater(r);
    }

    void update(TradeListResponse[] trades) {
        if (this.listData == null)
            return;
        if (this.listField == null)
            return;
        if (trades == null)
            return;

        int selected = this.listField.getSelectedIndex();

        if (!(this.listData instanceof TradeListResponse[]))
            return;

        Hashtable v = new Hashtable();
        for (int i = 0; i < this.listData.length; i++) {
            v.put(new Long(((TradeListResponse) this.listData[i]).getId()), this.listData[i]);
        }

        for (int i = 0; i < trades.length; i++) {
            long l = trades[i].getId();
            if (v.get(new Long(l)) != null) {
                v.put(new Long(l), trades[i]);
            } else {
                v.put(new Long(l), trades[i]);
            }
        }

        Enumeration e = v.elements();
        this.listData = new TradeListResponse[v.size()];
        int i = 0;
        while (e.hasMoreElements()) {
            this.listData[i] = ((TradeListResponse) e.nextElement());
            i++;
        }

        TradeListResponse.sort((TradeListResponse[]) (TradeListResponse[]) this.listData);

        Runnable r = new Runnable() {
            private int selected;

            public void run() {
                TradesListField.this.listField.setCallback(TradesListField.this.listFieldCallBack);
                TradesListField.this.listField.setSize(TradesListField.this.listData.length);
                if (TradesListField.this.listData.length > this.selected)
                    TradesListField.this.listField.setSelectedIndex(this.selected);
                TradesListField.this.listField.invalidate();
            }
        };
        UiApplication.getUiApplication().invokeLater(r);
    }

    public Quote getQuote(String symbol) {
        for (int i = 0; (this.quotes != null) && (i < this.quotes.length); i++) {
            if ((symbol != null) && (this.quotes[i] != null)
                    && (symbol.equals(this.quotes[i].getSymbol()))) {
                return this.quotes[i];
            }
        }
        return null;
    }

    public void setCallback(TradesView callback) {
        this.callback = callback;
    }

    private class ListCallBack extends AbstractListFieldCallBack {
        private Bitmap gained = Bitmap.getBitmapResource("pips-gained-51x24.png");
        private Bitmap lost = Bitmap.getBitmapResource("pips-lost-51x24.png");

        public ListCallBack() {
            Bitmap bg = Bitmap.getBitmapResource("trades-row-480x70.png");
            Bitmap bgSelected = Bitmap.getBitmapResource("trades-row-selected-480x70.png");

            setBg(bg);
            setBgSelected(bgSelected);
        }

        public void drawListRow(ListField list, Graphics graphics, int index, int y, int w) {
            Object o = get(list, index);

            PositionsListResponse currentRow = null;

            if ((o != null) && ((o instanceof TradeListResponse))) {
                currentRow = (TradeListResponse) get(list, index);
            } else {
                if ((o != null) && ((o instanceof PositionsListResponse))) {
                    drawListRowPosition(list, graphics, index, y, w);

                    return;
                }
                return;
            }

            if (currentRow == null)
                return;

            Quote currentRowQuote = TradesListField.this.getQuote(currentRow.getSymbol());

            if (currentRowQuote == null)
                ;
            Bitmap icon = null;

            Font originalFont = graphics.getFont();
            int originalColor = graphics.getColor();
            int height = list.getRowHeight();

            drawBackground(graphics, 0, y, w, height,
                    TradesListField.this.listField.getSelectedIndex() == index);

            int h = list.getRowHeight();
            int fontHeight = 24;
            Font font28Plain = DefaultController.getComponentFont().derive(0, fontHeight);

            graphics.setColor(16119285);
            graphics.setFont(font28Plain);
            graphics.drawText(currentRow.getSymbol(), 12, y + (h - 2 - fontHeight) / 2, 0x30 | 0x6);

            Symbol symbol = Model.getModel().getSymbol(currentRow.getSymbol());
            String profit = "updating...";
            String bid = "";
            String ask = "";
            double prof = 0.0D;
            int precious = -1;
            if ((symbol != null) && (currentRowQuote != null)) {
                precious = symbol.getPrecision();

                if (currentRow.getDir().equalsIgnoreCase("L")) {
                    prof = (currentRowQuote.getBid() - currentRow.getPrice()) / symbol.getPiploc();
                    profit = StringUtils.formatCurrency(StringUtils.columnRound(prof, 2));
                } else if (currentRow.getDir().equalsIgnoreCase("S")) {
                    prof = (currentRow.getPrice() - currentRowQuote.getAsk()) / symbol.getPiploc();
                    profit = StringUtils.formatCurrency(StringUtils.columnRound(prof, 2));
                }

                if (prof > 0.0D)
                    icon = this.gained;
                else if (prof < 0.0D) {
                    icon = this.lost;
                }
                bid = StringUtils.formatDouble(currentRowQuote.getBid(), precious);
                ask = StringUtils.formatDouble(currentRowQuote.getAsk(), precious);
            }

            if (profit != null) {
                int profitWidth = 125;
                if (profit.indexOf("updating") > -1) {
                    graphics.setFont(font28Plain.derive(0, 20));
                    graphics.drawText(profit, 135, y + (h - 2 - fontHeight) / 2, 0x30 | 0x4,
                            profitWidth);
                } else {
                    graphics.drawText(profit, 105, y + (h - 2 - fontHeight) / 2, 0x30 | 0x4,
                            profitWidth);
                }
                graphics.setFont(font28Plain);
            }

            if (icon != null) {
                drawImage(graphics, 231, y, height, icon);
            }

            if (currentRow != null) {
                String dir = currentRow.getDir().equalsIgnoreCase("L") ? "LONG" : "SHORT";
                dir = dir + " @";
                String at = Double.toString(currentRow.getPrice());
                String units = Integer.toString(currentRow.getUnits()) + " UNITS";
                int x = 270;
                int minWidth = 120;

                String tp = "";
                String sl = "";
                String ts = "";
                if (((currentRow instanceof TradeListResponse))
                        && (((TradeListResponse) currentRow).getTake_profit() > 0.0D)) {
                    tp = Double.toString(((TradeListResponse) currentRow).getTake_profit());
                }
                if (((currentRow instanceof TradeListResponse))
                        && (((TradeListResponse) currentRow).getStop_loss() > 0.0D)) {
                    sl = Double.toString(((TradeListResponse) currentRow).getStop_loss());
                }
                if (((currentRow instanceof TradeListResponse))
                        && (((TradeListResponse) currentRow).getTrailing_stop() > 0.0D)) {
                    double pips = symbol.getPips(((TradeListResponse) currentRow)
                            .getTrailing_stop());
                    ts = Double.toString(pips);
                }
                Font limitsFont = DefaultController.getComponentFontTall(10);

                int k = 0;
                int i = limitsFont.getAdvance(ts);
                int j = limitsFont.getAdvance(tp);
                k = limitsFont.getAdvance(sl);
                int max = Math.max(i, j);
                max = Math.max(max, k);

                if ((60 < max) && (max < 70)) {
                    minWidth += 30;
                } else if ((50 < max) && (max < 60)) {
                    minWidth += 40;
                } else if ((40 < max) && (max < 50)) {
                    minWidth += 55;
                } else if (max < 40) {
                    minWidth += 80;
                }

                graphics.setFont(font28Plain.derive(0, 15));
                graphics.drawText(units, x, y + 6 * this.verticalPadding, 0x30 | 0x4, minWidth);
                graphics.setFont(font28Plain.derive(0, 15));
                graphics.drawText(dir, x, y + 2 * this.verticalPadding + (h - 15 - 8) / 2,
                        0x4 | 0x30, minWidth);
                graphics.setFont(font28Plain.derive(1, 15));
                graphics.drawText(at, x,
                        y + 2 * this.verticalPadding + (h - 8 - this.plain22.getHeight()),
                        0x4 | 0x30, minWidth);

                x = 388;
                minWidth = 82;
                graphics.setFont(limitsFont);

                graphics.setColor(8956419);
                graphics.drawText(tp + " TP", x, y + 15, 0x30 | 0x5, minWidth);
                graphics.setColor(14287362);
                graphics.drawText(sl + " SL", x, y + 30, 0x30 | 0x5, minWidth);
                graphics.setColor(16762898);
                graphics.drawText(ts + " TS", x, y + 45, 0x30 | 0x5, minWidth);
            }

            graphics.setFont(originalFont);
            graphics.setColor(originalColor);
        }

        public void drawListRowPosition(ListField list, Graphics graphics, int index, int y, int w) {
            Object o = get(list, index);

            PositionsListResponse currentRow = null;
            if ((o != null) && ((o instanceof PositionsListResponse)))
                currentRow = (PositionsListResponse) get(list, index);
            else {
                return;
            }

            if (currentRow == null)
                return;

            Quote currentRowQuote = TradesListField.this.getQuote(currentRow.getSymbol());

            if (currentRowQuote == null)
                ;
            Bitmap icon = null;

            Font originalFont = graphics.getFont();
            int originalColor = graphics.getColor();
            int height = list.getRowHeight();

            drawBackground(graphics, 0, y, w, height,
                    TradesListField.this.listField.getSelectedIndex() == index);

            int h = list.getRowHeight();
            int fontHeight = 28;
            Font font28Plain = DefaultController.getComponentFont().derive(0, fontHeight);

            graphics.setColor(16119285);
            graphics.setFont(font28Plain);
            graphics.drawText(currentRow.getSymbol(), 14, y + (h - 2 - fontHeight) / 2, 0x30 | 0x6);

            Symbol symbol = Model.getModel().getSymbol(currentRow.getSymbol());
            String profit = "updating...";
            String bid = "";
            String ask = "";
            double prof = 0.0D;
            int precious = -1;
            if ((symbol != null) && (currentRowQuote != null)) {
                precious = symbol.getPrecision();

                if (currentRow.getDir().equalsIgnoreCase("L")) {
                    prof = (currentRowQuote.getBid() - currentRow.getPrice()) / symbol.getPiploc();
                    profit = StringUtils.formatDouble(StringUtils.columnRound(prof, 2), 1);
                } else if (currentRow.getDir().equalsIgnoreCase("S")) {
                    prof = (currentRow.getPrice() - currentRowQuote.getAsk()) / symbol.getPiploc();
                    profit = StringUtils.formatDouble(StringUtils.columnRound(prof, 2), 1);
                }

                if (prof > 0.0D)
                    icon = this.gained;
                else if (prof < 0.0D) {
                    icon = this.lost;
                }
                bid = StringUtils.formatDouble(currentRowQuote.getBid(), precious);
                ask = StringUtils.formatDouble(currentRowQuote.getAsk(), precious);
            }

            if (profit != null) {
                int profitWidth = 130;
                if (profit.indexOf("updating") > -1) {
                    graphics.setFont(font28Plain.derive(0, 22));
                    graphics.drawText(profit, 240 - profitWidth / 2, y + (h - 2 - fontHeight) / 2,
                            0x30 | 0x4, profitWidth);
                } else {
                    graphics.drawText(profit, 127, y + (h - 2 - fontHeight) / 2, 0x30 | 0x4,
                            profitWidth);
                }
                graphics.setFont(font28Plain);
            }

            if (icon != null) {
                drawImage(graphics, 255, y, height, icon);
            }

            if (currentRow != null) {
                String dir = currentRow.getDir().equalsIgnoreCase("L") ? "LONG" : "SHORT";
                dir = dir + " @" + Double.toString(currentRow.getPrice());
                String units = Integer.toString(currentRow.getUnits()) + " UNITS";
                int x = 322;
                int minWidth = 142;
                graphics.setFont(font28Plain.derive(0, 16));
                graphics.drawText(dir, x, y + 4 * this.verticalPadding, 0x30 | 0x5, minWidth);
                graphics.setFont(font28Plain.derive(1, 16));
                graphics.drawText(units, x,
                        y + this.verticalPadding + (h - 10 - this.plain22.getHeight()), 0x30 | 0x5,
                        minWidth);
            }

            graphics.setFont(originalFont);
            graphics.setColor(originalColor);
        }

        protected void drawBorder(Graphics graphics, int x, int y, int width, int height) {
            graphics.setColor(8421504);
            graphics.drawLine(x - 1, y, x + width - 1, y);
            graphics.drawLine(x - 1, y, x - 1, y + height - 1);

            graphics.drawLine(x + width, y - 1, x + width, y + height - 1);
            graphics.drawLine(x - 1, y + height - 1, x + width - 1, y + height - 1);
        }

        public Object get(ListField list, int index) {
            try {
                return TradesListField.this.listData[index];
            } catch (ArrayIndexOutOfBoundsException a) {
            }
            return null;
        }
    }
}
